const { Service } = require('egg')
const { tableToList, zc } = require('../utils/tools')

/**
 * * 班级课表单元格数据处理
 * @param {string[][]} list *
 * @return {Array<string>} *
 */
function dealClass(list) {
  try {
    const need = []
    for (const i of list) {
      if (i[0].includes('体育')) break // 体育信息不确定不进行统计
      const reg = /\(([^)]*)\)[^(]*$/ // 匹配字符串中最后一个括号及其内容
      const N = i[0]
      const W = reg.exec(i[1])[1]
      const T = i[1].replace(W, '').replace('()', '')
      const P = zc(W)
      const R = i[2] || ''
      need.push({
        N, T, W, P, R,
      })
    }
    /* 合并名称和上课地点相同，上课周次不同的课程 */
    if (need.length > 1) {
      const sub = []
      for (let i = 0; i < need.length - 1; i++) {
        for (let j = i + 1; j < need.length; j++) {
          if (need[i].N === need[j].N && need[i].R === need[j].R) {
            need[i].W = `${need[i].W.replace('周', '')},${need[j].W}`
            need[i].P = need[i].P.concat(need[j].P)
            sub.push(j)
          }
        }
      }
      for (const i of sub) {
        need.splice(i, 1)
      }
    }
    return need
  } catch (err) {
    console.log('err', err)
    throw err
  }
}

/**
 * 教师课表单元格数据处理
 * @param {string[][]} list *
 * @return {Array<string>} *
 */
function dealTeacher(list) {
  try {
    const need = []
    const sign = []
    for (const i of list) {
      const reg = /\(\d.*周\)/
      const W = i[1].match(reg)[0].replace('(', '').replace(')', '')
      need.push({
        N: i[0],
        C: i[1].replace(W, '').replace('()', ''),
        W,
        P: zc(W),
        R: i[2] || '',
      })
    }
    /* 课程、上课地点、上课班级都相同，但周次不同，将周次合并 */
    if (need.length > 1) {
      const sub = []
      for (let i = 0; i < need.length - 1; i++) {
        if (sub.indexOf(i) !== -1) continue
        for (let j = i + 1; j < need.length; j++) {
          if (need[i].N === need[j].N
            && need[i].R === need[j].R && need[i].C === need[j].C) {
            need[i].W = `${need[i].W.replace('周', '')},${need[j].W}`
            need[i].P = need[i].P.concat(need[j].P)
            sub.push(j)
          }
        }
      }
      need.forEach((e, i) => {
        if (sub.indexOf(i) === -1) sign.push(e)
      })
      return sign
    }
    return need
  } catch (err) {
    console.log('err', err)
    throw err
  }
}

/**
 * 教室课表单元格数据处理
 * @param {string[][]} list *
 * @return {Array<string>} *
 */
function dealClassroom(list) {
  const sign = []
  const need = []
  for (const i of list) {
    const reg = /\(\d.*周\)/
    const W = i[1].match(reg)[0].replace('(', '').replace(')', '')
    need.push({
      N: i[0],
      T: i[1].replace(W, '').replace('()', ''),
      C: i[2],
      W,
      P: zc(W),
    })
  }
  /* 解决两个问题
      1. 课程名称、上课地点、老师都相同，但周次不同，将周次合并
      2. 大学体育里面同一时间段中一个上课地点，多个老师授课不同班级，将老师合并
   */
  if (need.length > 1) {
    const sub = []
    for (let i = 0; i < need.length - 1; i++) {
      if (sub.indexOf(i) !== -1) { continue }
      for (let j = i + 1; j < need.length; j++) {
        // 1
        if (need[i].N === need[j].N
          && need[i].C === need[j].C && need[i].T === need[j].T) {
          need[i].W = `${need[i].W.replace('周', '')},${need[j].W}`
          need[i].P = need[i].P.concat(need[j].P)
          sub.push(j)
        }
        // 2
        else if (need[i].N === need[j].N
          && need[i].C === need[j].C && need[i].W === need[j].W) {
          need[i].T = `${need[i].T},${need[j].T}`
          sub.push(j)
        }
      }
    }
    need.forEach((e, i) => {
      if (sub.indexOf(i) === -1) { sign.push(e) }
    })
    return sign
  }
  return need
}

const defaultTime = [
  '08:00~08:45', '08:55~09:40', '10:00~10:45', '10:55~11:40',
  '14:00~14:45', '14:55~15:40', '15:50~16:35', '16:45~17:30',
  '18:30~19:15', '19:25~20:10',
] // 记录每节课上课时间

const emptyTable = {}
defaultTime.forEach((e, i) => {
  emptyTable[`${i + 1}`] = [[], [], [], [], [], [], []]
})

module.exports = class CourseService extends Service {
  /**
   * * 学生个人课表查询
   * @param {string} term 学期
   * @return {Object} *
   */
  async table(term) {
    const Cookie = this.ctx.state.Cookie
    const apiUrl = `${this.ctx.state.baseUrl}/jsxsd/xskb/xskb_list.do`
    const res = await this.ctx.curl(apiUrl, {
      method: 'POST',
      headers: {
        Cookie,
        'Content-Type': 'application/x-www-form-urlencoded',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
      },
      data: {
        cj0701id: '',
        zc: '',
        demo: '',
        xnxq01id: term,
        sfFD: '1',
      },
      timeout: 10000,
    })
    if (res.status === 200) {
      try {
        if (res.data.toString().includes('课表暂未公布')) {
          return {
            table: emptyTable, defaultTime, note: '课表暂未公布', status: false,
          }
        }
        const cb = (cell, rowIndex, colIndex, $) => {
          const value = cell.text().trim().replace(/\s/g, '') // 获取单元格内容
          if (rowIndex > 0 && rowIndex <= 5 && colIndex > 0) {
            const tem = [{
              N: '', T: '', W: '', R: '', P: [],
            }]
            cell.find('.kbcontent').each((_, kbcontent) => {
              $(kbcontent).contents().each((__, e) => {
                const str = $(e).text().replace(/\s/g, '')
                const nodeName = e.name // 标签名称
                const nodeType = e.type // 节点类型
                if (str !== '' && nodeName !== 'br') {
                  if (nodeType === 'text' && nodeName === undefined && str.includes('-----') === false) {
                    tem[tem.length - 1].N = str // 名称
                  }
                  else if (nodeName === 'font') {
                    const attribs = e.attribs
                    if (attribs.title === '周次(节次)') {
                      tem[tem.length - 1].W = str.replace(/\[(.*?)\]/, '')
                      tem[tem.length - 1].P = zc(str.replace(/\[(.*?)\]/, ''))
                    }
                    else if (attribs.title === '老师') tem[tem.length - 1].T = str
                    else if (attribs.title === '教室') tem[tem.length - 1].R = str
                  }

                  if (str.includes('-----')) { // 分隔线后是另一个课程
                    tem.push({
                      N: '', T: '', W: '', R: '',
                    })
                  }
                }
              })
            })
            return tem
          }
          return value
        }
        const tableList = tableToList(res.data.toString(), '#kbtable', '', cb)
        console.log('tableList', tableList)
        const note = tableList[tableList.length - 1][1] // 记录备注信息

        const Ntable = {}
        const period = ['', '1-2', '3-4', '5-6', '7-8', '9-10']

        tableList.forEach((e, i) => {
          if (i > 0 && i < tableList.length - 1 && e[1]) {
            Ntable[period[i]] = []

            for (let j = 1; j < e.length; j++) {
              const infoList = e[j]
              const tem = infoList
                .map((item) => (item.N === '' && item.T === '' && item.W === '' && item.R === '' ? '' : item))
                .filter((str) => str !== '')
              Ntable[period[i]].push(tem)
            }
          }
        })

        const resultTable = {}
        for (const key in Ntable) {
          resultTable[key.split('-')[0]] = Ntable[key]
          resultTable[key.split('-')[1]] = Ntable[key]
        }
        return {
          table: resultTable, time: defaultTime, note, status: true,
        }
      }
      catch (err) {
        console.log('err', err)
        throw err
      }
    }
    return {
      table: emptyTable, time: defaultTime, note: '', status: false,
    }
  }

  /**
   * * 班级课表查询
   * @param {string} term 学期
   * @param {{label:string, value:string}} yx 院系
   * @param {{label:string, value:string}} nj 年级
   * @param {{label:string, value:string}} zy 专业
   * @param {{label:string, value:string}} name 班级
   * @return {object} *
   */
  async Ctable(term, yx, nj, zy, name) {
    const Cookie = this.ctx.state.Cookie
    const apiUrl = `${this.ctx.state.baseUrl}/jsxsd/kbcx/kbxx_xzb_ifr`
    const res = await this.ctx.curl(apiUrl, {
      method: 'POST',
      data: {
        xnxqh: term,
        skyx: yx.value,
        sknj: nj.value,
        skzy: zy.value,
        zc1: '',
        zc2: '',
        jc1: '',
        jc2: '',
      },
      headers: {
        Cookie,
        'Content-Type': 'application/x-www-form-urlencoded',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
      },
      timeout: 10000,
    })

    if (res.status === 200) {
      try {
        const cb = (cell, rowIndex, colIndex, $) => {
          const value = cell.text().trim().replace(/\s/g, '') // 获取单元格内容
          if (rowIndex > 1 && colIndex > 0) {
            if (value === '') return []
            const item = []
            $(cell).find('div').each((i, contents) => {
              item.push([])
              $(contents).contents().each((_, v) => {
                if (v.type === 'text') item[i].push(v.data.replace(/\s/g, ''))
              })
            })
            return dealClass(item)
          }
          return value
        }
        const tableList = tableToList(res.data.toString(), '#kbtable', '', cb)
        if (tableList.length < 3) return { table: emptyTable, time: defaultTime, note: '' }
        const table = {}
        const row = tableList.filter((e) => e[0] === name.label)[0]
        const period = ['1-2', '3-4', '5-6', '7-8', '9-10']
        for (let i = 0; i < period.length; i++) {
          table[period[i]] = []
          for (let j = 0; j < 7; j++) {
            const idx = i + (j * 5) + j + 1
            table[period[i]].push(row[idx])
          }
        }
        const resultTable = {}
        for (const key in table) {
          resultTable[key.split('-')[0]] = table[key]
          resultTable[key.split('-')[1]] = table[key]
        }
        return { table: resultTable, time: defaultTime, note: '' }
      } catch (err) {
        console.log('err', err)
        throw err
      }
    }
    return { table: emptyTable, time: defaultTime, note: '' }
  }

  /**
   * * 教师课表查询
   * @param {string} term 学期
   * @param {{label:string, value:string}} yx 院系
   * @param {{label:string, value:string}} name 教师姓名
   * @return {object} *
   */
  async Ttable(term, yx, name) {
    const Cookie = this.ctx.state.Cookie
    const apiUrl = `${this.ctx.state.baseUrl}/jsxsd/kbcx/kbxx_teacher_ifr`
    const res = await this.ctx.curl(apiUrl, {
      method: 'POST',
      data: {
        xnxqh: term,
        skyx: yx.value,
        jszc: '',
        zc1: '',
        zc2: '',
        jc1: '',
        jc2: '',
      },
      headers: {
        Cookie,
        'Content-Type': 'application/x-www-form-urlencoded',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
      },
      timeout: 10000,
    })
    if (res.status === 200) {
      try {
        const cb = (cell, rowIndex, colIndex, $) => {
          const value = cell.text().trim().replace(/\s/g, '') // 获取单元格内容
          if (rowIndex > 1 && colIndex > 0) {
            if (value === '') return []
            const item = []
            $(cell).find('div').each((i, contents) => {
              item.push([])
              $(contents).contents().each((_, v) => {
                if (v.type === 'text') item[i].push(v.data.replace(/\s/g, ''))
              })
            })
            return dealTeacher(item)
          }
          return value
        }
        const tableList = tableToList(res.data.toString(), '#kbtable', '', cb)
        if (tableList.length < 3) return { table: emptyTable, time: defaultTime, note: '' }
        const row = tableList.filter((e) => e[0] === name.label)[0]
        const table = {}
        const period = ['1-2', '3-4', '5-6', '7-8', '9-10']
        for (let i = 0; i < period.length; i++) {
          table[period[i]] = []
          for (let j = 0; j < 7; j++) {
            const idx = i + (j * 5) + j + 1
            table[period[i]].push(row[idx])
          }
        }

        const resultTable = {}
        for (const key in table) {
          resultTable[key.split('-')[0]] = table[key]
          resultTable[key.split('-')[1]] = table[key]
        }
        return { table: resultTable, time: defaultTime, note: '' }
      } catch (err) {
        console.log('err', err)
        throw err
      }
    }
    return { table: emptyTable, time: defaultTime, note: '' }
  }

  /**
   * * 教室课表查询
   * @param {string} term 学期
   * @param {{label:string, value:string}} xq 校区
   * @param {{label:string, value:string}} jxl 教学楼
   * @param {{label:string, value:string}} name 教室名称
   * @return {object} *
   */
  async Rtable(term, xq, jxl, name) {
    const Cookie = this.ctx.state.Cookie
    const apiUrl = `${this.ctx.state.baseUrl}/jsxsd/kbcx/kbxx_classroom_ifr`
    const res = await this.ctx.curl(apiUrl, {
      method: 'POST',
      data: {
        xnxqh: term,
        skyx: '',
        xqid: xq.value,
        jzwid: jxl.value,
        zc1: '',
        zc2: '',
        jc1: '',
        jc2: '',
      },
      headers: {
        Cookie,
        'Content-Type': 'application/x-www-form-urlencoded',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
      },
      timeout: 10000,
    })
    if (res.status === 200) {
      try {
        const cb = (cell, rowIndex, colIndex, $) => {
          const value = cell.text().trim().replace(/\s/g, '') // 获取单元格内容
          if (rowIndex > 1 && colIndex > 0) {
            if (value === '') return []
            const item = []
            $(cell).find('div').each((i, contents) => {
              item.push([])
              $(contents).contents().each((_, v) => {
                if (v.type === 'text') item[i].push(v.data.replace(/\s/g, ''))
              })
            })
            return dealClassroom(item)
          }
          return value
        }
        const tableList = tableToList(res.data.toString(), '#kbtable', '', cb)
        if (tableList.length < 3) return { table: emptyTable, time: defaultTime, note: '' }
        const row = tableList.filter((e) => e[0] === name.label)[0]
        const table = {}
        const period = ['1-2', '3-4', '5-6', '7-8', '9-10']
        for (let i = 0; i < period.length; i++) {
          table[period[i]] = []
          for (let j = 0; j < 7; j++) {
            const idx = i + (j * 5) + j + 1
            table[period[i]].push(row[idx])
          }
        }

        const resultTable = {}
        for (const key in table) {
          resultTable[key.split('-')[0]] = table[key]
          resultTable[key.split('-')[1]] = table[key]
        }
        return { table: resultTable, time: defaultTime, note: '' }
      } catch (err) {
        console.log('err', err)
        throw err
      }
    }
    return { table: emptyTable, time: defaultTime, note: '' }
  }
}
